# -*- coding: utf-8 -*-
import logging

from celery.execute import send_task
from celery.result import BaseAsyncResult
from celery.backends import default_backend
from celery.task.control import inspect
from celery.task.control import revoke, discard_all, ping, rate_limit
from pylons import config


from pylons.configuration import asbool

log = logging.getLogger(__name__)

class CommandQueue(object):

    def __init__(self, queue, routing_key, exchange, exchange_type):
        self.inspector = inspect()
        self.queue = queue
        self.routing_key = routing_key
        self.exchange = exchange
        self.exchange_type = exchange_type


    def available_commands(self):
        log.info("query available commands")
        return self.inspector.registered_tasks()

    def statistics(self):
        log.info("query stats")
        return self.inspector.stats()

    def revoked(self):
        log.info("query revoked commands")
        return self.inspector.revoked()

    def scheduled(self, safe=False):
        log.info("query scheduled commands")
        return self.inspector.scheduled(safe=safe)

    def active(self, safe=False):
        log.info("query active commands")
        return self.inspector.active(safe=safe)

    def enable_events(self):
        log.info("enable events")
        return self.inspector.enable_events()

    def disable_events(self):
        log.info("disable events")
        return self.inspector.disable_events()

    def discard_all_pending_commands(self):
        log.info("discard all pending commands")
        return discard_all()

    def ping_workers(self):
        log.info("ping workers")
        return ping()

    def rate_limit(self, command, rate_limitation):
        log.info("set rate_limit for command: %s to %s", command, repr(rate_limitation))
        return rate_limit(command, rate_limitation)


    def execute(self, command, site=None,  **kwargs):
        log.info("execute command: %s", command)
        routing_key = self.routing_key
        exchange = self.exchange
        exchange_type = self.exchange_type
        if site is not None:
            routing_key = site
            exchange = site
            return send_task(command, kwargs=kwargs,
                             routing_key=routing_key,
                             exchange=exchange)
        else:
            return send_task(command, kwargs=kwargs)

    def execute_wait(self, command, timeout=None, site=None, **kwargs):
        log.info("execute command and wait %s for result: %s", timeout, command)
        routing_key = self.routing_key
        exchange = self.exchange
        exchange_type = self.exchange_type
        if site is not None:
            routing_key = site
            exchange = site
            #print site, routing_key, exchange, exchange_type
            return send_task(command, kwargs=kwargs,
                             routing_key=routing_key,
                             exchange=exchange).wait(timeout)
        else:
            #print routing_key, exchange, exchange_type
            return send_task(command, kwargs=kwargs).wait(timeout)

    def cancel(self, commandUuid):
        log.info("cancel command: %s", commandUuid)
        return revoke(commandUuid)

    def status(self, commandUuid):
        log.info("query command status: %s", commandUuid)
        result = BaseAsyncResult(commandUuid, default_backend)
        return result.status

    def ready(self, commandUuid):
        log.info("query command ready: %s", commandUuid)
        result = BaseAsyncResult(commandUuid, default_backend)
        # return true is command executed successfully or raise exception
        return result.ready()

    def successful(self, commandUuid):
        log.info("query command successful: %s", commandUuid)
        result = BaseAsyncResult(commandUuid, default_backend)
        # return true is command executed successfully
        return result.successful()

    def failed(self, commandUuid):
        log.info("query command failed: %s", commandUuid)
        result = BaseAsyncResult(commandUuid, default_backend)
        # return true if the command failed by exception
        return result.failed()

    def traceback(self, commandUuid):
        log.info("query command traceback: %s", commandUuid)
        result = BaseAsyncResult(commandUuid, default_backend)
        return result.traceback

    def result(self, commandUuid):
        log.info("query command result: %s", commandUuid)
        result = BaseAsyncResult(commandUuid, default_backend)
        return result.result

def parse_command_queue_options(config):
    ret = {}
    ret['queue'] = config.get('amqp.routing.default.queue','auto')
    ret['routing_key'] = config.get('amqp.routing.default.routing_key','auto')
    ret['exchange'] = config.get('amqp.routing.default.exchange','auto')
    ret['exchange_type'] = config.get('amqp.routing.default.exchange_type','direct')
    print ret
    return ret
